/************************************************************************
 File:			Master.cpp
 Author:		Justin England
 Class:			CSC 470
 Instructor:	Dr. Penaloza
 Date:
 Description:	Class file for master device on ethernet.
 
 Known bugs/missing features:
 Modifications:
 Date                Comment            
 ----    ------------------------------------------------
 ************************************************************************/

#include <QtGui>
#include <QDebug>
#include "Master.h"
#include "Ethernet.h"

/************************************************************************
 Function:		Master()
 Author:		Justin England
 
 Description:	Constructor for Master object.  Sets inital values
				for the needed vars

 Parameters:	int thisM	- the ID of this master object
				int totalM	- the total number of master objects
 
 ************************************************************************/

Master::Master(int thisM, int totalM)
{
	
	thisMaster = thisM;					// get the number of this master
	totalMasters = totalM;				// get the total number of masters

	collisions	= 0;					// initalize collisions counter
	rxPackets	= 0;					// initalize received counter
	txPackets	= 0;					// initalize transmit counter
	
	sendPacketTimer = new QTimer;		// create timer for this master
	
	// Connect timer's timeout to the txPacket method.
	// This will simulate a device attemping to send data
	// to the ethernet at random intervals
	connect(sendPacketTimer, SIGNAL(timeout()), this, SLOT(txPacket()) );
	sendPacketTimer->setInterval(random() %100);	// set random interval
}

/************************************************************************
 Function:		~Master()
 Author:		Justin England
 
 Description:	Destructor for master object.  Just a place holder
 
 Parameters:	<none>
 
 ************************************************************************/

Master::~Master()
{
}

/************************************************************************
 Function:		attachToEthernet()
 Author:		Justin England
 
 Description:	Receives a pointer to the ethernet object to which this
				master is connected.
 
 Parameters:	Ethernet *np	- pointer to ethernet object
 
 ************************************************************************/

void Master::attachToEthernet(Ethernet *np)
{
	// get pointer to the ethernet to which this master are connected
	// and set into this objects ethernetPointer var
	ethernetPointer = np;
}

/************************************************************************
 Function:		start()
 Author:		Justin England
 
 Description:	Start generating packets at random times to send to 
				the ethernet.
 
 Parameters:	<none>
 
 ************************************************************************/

void Master::start(void)
{
	// start timer to begin random data transmissions to ethernet
	sendPacketTimer->start();
}

/************************************************************************
 Function:		txPacket()
 Author:		Justin England
 
 Description:	attempts to transmit a packet to the ethernet.  This
				method will be called at a random time interval
 
 Parameters:	<none>
 
 ************************************************************************/

void Master::txPacket(void)
{
	// check if the ethernet is busy
	if(ethernetPointer->isBusy() == FALSE)
	{
		// ethernet is not busy, put data on ethernet
		ethernetPointer->putOnEthernet(random());

		// generate a random master to act as receiver for this packet
		int receiver = random() % totalMasters;

		// ask ethernet to accept packet with current master
		// and random receiver
		
		// check if there was a collision on ethernet
		if(!ethernetPointer->acceptPacket(thisMaster, receiver) )
		{
			// there was a collision, update collision counter 
			// for this master, and set random time to re-transmit packet
			
			qDebug() << "Master: " << thisMaster << "COLLISION";
			collisions++;
			
			sendPacketTimer->setInterval(random() % 100);
		}
		
		// packet successfully accepted on the ethernet, update counter
		else
		{
			txPackets++;
		}

	}
}

/************************************************************************
 Function:		rxPacket()
 Author:		Justin England
 
 Description:	called when a packet was sent to this master as a receiver
				and updates received packet counter
 
 Parameters:	<none>
 
 ************************************************************************/

void Master::rxPacket(void)
{
	rxPackets++;				// update received packet count
}


